package com.imot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imot.handler.ImotExciption;
import com.imot.mapper.EmaRecordMapper;
import com.imot.mapper.TargetParametersMapper;
import com.imot.pojo.dto.FaultTestDto;
import com.imot.pojo.entity.*;
import com.imot.pojo.vo.*;
import com.imot.response.Result;
import com.imot.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * ClassName: EmaServiceImpl
 * Description:
 * date: 2023/11/7 17:00
 *
 * @author imot-jiah.wang
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class EmaServiceImpl implements EmaService {
    private final IEmaRecordService recordService;
    private final ITargetParametersService targetService;
    private final IHardwareUsageService hardUsageService;
    private final ISoftwareUsageService softUsageService;
    private final IDictService dictService;
    private final IEmaExceptionRecordService exceptionRecordService;
    private final IExceptionThresholdsService exceptionThresholdsService;

    private final TargetParametersMapper targetParametersMapper;
    private final EmaRecordMapper recordMapper;

    /**
     * 获取状态态势的数据页面
     */
    @Override
    public Result getEmaState() {
        /**
         * 根据id倒序取出最后一个数据，达到数据的实时展示的效果
         */
        LambdaQueryWrapper<EmaRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(EmaRecord::getId);
        wrapper.last("limit 1");
        EmaRecord emaRecord = recordService.getOne(wrapper) != null ? recordService.getOne(wrapper) : null;
        log.info("获取机电作动器的状态态势的Service层的获取最新数据{}", emaRecord);
        if (emaRecord == null) return Result.success();
        /**
         *获取最新的ema数据，把这个数据复制给返回的vo
         */
        EmaStateVo emaStateVo = new EmaStateVo();
        BeanUtils.copyProperties(emaRecord, emaStateVo);
        emaStateVo.setWeeklyTests((float) 23);
        emaStateVo.setWeeklyRunTime((long) 6000);

        /**
         * 获取目标参数，把这个值赋值给vo
         */
        List<TargetParameters> list = targetService.list();
        TargetParameters targetParameter = list.get(0);
        /**
         * 如果没有目标参数的话，就把设备的状态态势返回，不返回目标参数
         */
        if (ObjectUtils.isEmpty(list)) {
            return Result.success(emaStateVo);
        }
        log.info("获取机电作动器的状态态势的Service层的获取目标数据{}", targetParameter);
        BeanUtils.copyProperties(targetParameter, emaStateVo);
        /**
         * 拿出实时数据和目标数据进行计算算出，目标电流，目标转速，实验周环比和时长周环比
         */
        Float motorCurrent = emaRecord.getMotorCurrent();
        Float motorSpeed = emaRecord.getMotorSpeed();
        Float targetCurrent = targetParameter.getTargetCurrent();
        Float targetRpm = targetParameter.getTargetRpm();
        Float changeCurrent = (motorCurrent - targetCurrent) * 100 / targetCurrent;
        Float changeSpeed = (motorSpeed - targetRpm) * 100 / targetRpm;
        emaStateVo.setChangeCurrent(changeCurrent);
        emaStateVo.setChangeSpeed(changeSpeed);
        emaStateVo.setWeeklyTests(5F);

        return Result.success(emaStateVo);
    }

    @Override
    public Result getEmaNow() {
        LambdaQueryWrapper<EmaRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(EmaRecord::getId);
        wrapper.last("limit 1");
        EmaRecord emaRecord = recordService.getOne(wrapper);
        log.info("获取机电作动器的现在状态的Service层的获取实时数据{}", emaRecord);
        EmaNowVo emaNowVo = new EmaNowVo();
        BeanUtils.copyProperties(emaRecord, emaNowVo);

        List<TargetParameters> list = targetService.list();
        TargetParameters parameter = list.get(0);
        log.info("获取机电作动器的现在状态的Service层的获取目标数据{}", parameter);
        emaNowVo.setTargetCurrent(parameter.getTargetCurrent());
        emaNowVo.setTargetRpm(parameter.getTargetRpm());
        log.info("获取Vo：{}", emaNowVo);
        return Result.success(emaNowVo);
    }

    @Override
    public Result getEmaWaveData() {
        LocalDateTime end = LocalDateTime.now();
        LocalDateTime start = end.minusHours(1);


        LambdaQueryWrapper<EmaRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(EmaRecord::getTime, start);
        wrapper.le(EmaRecord::getTime, end);

        List<EmaRecord> list = recordService.list(wrapper);
        if (list.size() == 0) return Result.success();

        List<WaveVo> temperature = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getTemperature())).collect(Collectors.toList());
        List<WaveVo> thrust = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getThrust())).collect(Collectors.toList());
        List<WaveVo> supplyVoltage = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getSupplyVoltage())).collect(Collectors.toList());
        List<WaveVo> motorCurrent = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getMotorCurrent())).collect(Collectors.toList());
        List<WaveVo> motorSpeed = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getMotorSpeed())).collect(Collectors.toList());
        List<WaveVo> elecTorque = list.stream().map(emaRecord -> new WaveVo(emaRecord.getTime(), emaRecord.getElecTorque())).collect(Collectors.toList());

        WaveDataVo waveDataVo = new WaveDataVo();
        waveDataVo.setTemperature(temperature);
        waveDataVo.setThrust(thrust);
        waveDataVo.setSupplyVoltage(supplyVoltage);
        waveDataVo.setMotorCurrent(motorCurrent);
        waveDataVo.setMotorSpeed(motorSpeed);
        waveDataVo.setElecTorque(elecTorque);

//        LambdaQueryWrapper<TargetParameters> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.orderByDesc(TargetParameters::getId);
//        queryWrapper.last("limit 1");
//        TargetParameters targetParameters = targetService.getOne(queryWrapper);
//        Float targetRpm = targetParameters.getTargetRpm();
//        Float targetCurrent = targetParameters.getTargetCurrent();
//        Float minTempThresh = targetParameters.getMinTempThresh();
//        Float maxTempThresh = targetParameters.getMaxTempThresh();
//        Float minVoltThresh = targetParameters.getMinVoltThresh();
//        Float maxVoltThresh = targetParameters.getMaxVoltThresh();
//        waveDataVo.setTargetRpm(targetRpm);
//        waveDataVo.setTargetCurrent(targetCurrent);
//        waveDataVo.setMinTempThresh(minTempThresh);
//        waveDataVo.setMaxTempThresh(maxTempThresh);
//        waveDataVo.setMinVoltThresh(minVoltThresh);
//        waveDataVo.setMaxVoltThresh(maxVoltThresh);

        return Result.success(waveDataVo);
    }

    @Override
    public Result expDuration(LocalDate start, LocalDate end) {
        if (start == null && end == null) {
            LocalDate now = LocalDate.now();
            end = now;
            start = now.minusMonths(3);
        } else {
            start = start.minusDays(300);
            end = end.plusDays(300);
        }
        Period period = Period.between(start, end);
        int days = period.getDays();
        LambdaQueryWrapper<SoftwareUsage> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<HardwareUsage> wrapper1 = new LambdaQueryWrapper<>();

        wrapper.ge(SoftwareUsage::getEndTime, start);
        wrapper.le(SoftwareUsage::getEndTime, end);
        List<SoftwareUsage> softList = softUsageService.list(wrapper);
        log.info("expDuration Service层的softList监测：{}", softList);
        ArrayList<Map<LocalDate, Integer>> maps = new ArrayList<>();
        HashMap<LocalDate, Integer> softHashMap = new HashMap<>();
        for (SoftwareUsage softwareUsage : softList) {
            LocalDateTime endTime = softwareUsage.getEndTime();
            Integer duration = softwareUsage.getDuration();
            LocalDate date = endTime.toLocalDate();
            Integer sum = softHashMap.get(date);
            if (sum == null) {
                softHashMap.put(date, duration);
            } else {
                softHashMap.put(date, sum + duration);
            }
        }

        wrapper1.ge(HardwareUsage::getEndTime, start);
        wrapper1.le(HardwareUsage::getEndTime, end);
        List<HardwareUsage> hardList = hardUsageService.list(wrapper1);
        log.info("expDuration Service层的hardList监测：{}", hardList);
        HashMap<LocalDate, Integer> hardHashMap = new HashMap<>();
        for (HardwareUsage hardwareUsage : hardList) {
            LocalDateTime endTime = hardwareUsage.getEndTime();
            Integer duration = hardwareUsage.getDuration();
            LocalDate date = endTime.toLocalDate();
            Integer sum = hardHashMap.get(date);
            if (sum == null) {
                hardHashMap.put(date, duration);
            } else {
                hardHashMap.put(date, sum + duration);
            }
        }

        List<Map<String, Object>> hardHashMapList = new ArrayList<>();
        for (Map.Entry<LocalDate, Integer> entry : hardHashMap.entrySet()) {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("time", entry.getKey());
            hashMap.put("value", entry.getValue());
            hardHashMapList.add(hashMap);
        }

        List<Map<String, Object>> softHashMapList = new ArrayList<>();
        for (Map.Entry<LocalDate, Integer> entry : softHashMap.entrySet()) {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("time", entry.getKey());
            hashMap.put("value", entry.getValue());
            softHashMapList.add(hashMap);
        }

        DateVo dateVo = new DateVo();
        dateVo.setHardHashMapList(hardHashMapList);
        dateVo.setSoftHashMapList(softHashMapList);
        return Result.success(dateVo);
    }

    @Override
    public Result injectFault() {
        LambdaQueryWrapper<EmaRecord> emaRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        emaRecordLambdaQueryWrapper.orderByDesc(EmaRecord::getId);
        emaRecordLambdaQueryWrapper.last("limit 1");
        EmaRecord emaRecord = recordService.getOne(emaRecordLambdaQueryWrapper);

        String testType = emaRecord.getTestType();
        String testModel = emaRecord.getTestModel();
        String faultType = emaRecord.getFaultType();
        String testStartTime = emaRecord.getTestStartTime();
        String faultInjectTime = emaRecord.getFaultInjectTime();

        FaultDetailVo faultDetailVo = new FaultDetailVo();
        faultDetailVo.setTestType(testType);
        faultDetailVo.setFaultType(faultType);
        faultDetailVo.setTestModel(testModel);
        faultDetailVo.setTestStartTime(Integer.valueOf(testStartTime));
        faultDetailVo.setFaultInjectTime(Integer.valueOf(faultInjectTime));
        return Result.success(faultDetailVo);
    }

    @Override
    public Result statusCheck() {
        LambdaQueryWrapper<EmaRecord> emaRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        emaRecordLambdaQueryWrapper.orderByDesc(EmaRecord::getId);
        emaRecordLambdaQueryWrapper.last("limit 1");
        EmaRecord emaRecord = recordService.getOne(emaRecordLambdaQueryWrapper);
        String deviceName = emaRecord.getDeviceName();
        String deviceNumber = emaRecord.getDeviceNumber();
        String testStartTime = emaRecord.getTestStartTime();
        String faultInjectTime = emaRecord.getFaultInjectTime();
        String currentStatus = emaRecord.getCurrentStatus();

        WorkChekcVo workChekcVo = new WorkChekcVo();
        workChekcVo.setDeviceName(deviceName);
        workChekcVo.setDeviceCode(deviceNumber);
        workChekcVo.setTestStartTime(testStartTime);
        workChekcVo.setFaultInjectTime(faultInjectTime);
        workChekcVo.setStatus(currentStatus);

        return Result.success(workChekcVo);
    }

    @Override
    public Result runMonitoring() {
        LocalDateTime now = LocalDateTime.now();

        LambdaQueryWrapper<EmaRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(EmaRecord::getId);
        queryWrapper.last("limit 1");
        EmaRecord emaRecord = recordService.getOne(queryWrapper);
        LocalDateTime recordTime = emaRecord.getTime();
        Duration duration = Duration.between(recordTime, now);
        long minutes = duration.toMinutes();
//        if (minutes > 3) {
//            return Result.success();
//        }
        if (emaRecord == null) return Result.success();
        LambdaQueryWrapper<TargetParameters> wrapper = new LambdaQueryWrapper<>();
        wrapper.last("limit 1");
        TargetParameters targetParameters = targetService.getOne(wrapper);
        HashMap<String, String> alarmMessages = new HashMap<>();
        evaluateThreshold(emaRecord, targetParameters, alarmMessages);

        RunMonitoringVo runMonitoringVo = new RunMonitoringVo();
        BeanUtils.copyProperties(emaRecord, runMonitoringVo);

        runMonitoringVo.setAlarmMessages(alarmMessages);
        return Result.success(runMonitoringVo);
    }

    public void evaluateThreshold(EmaRecord emaRecord, TargetParameters targetParameters, HashMap<String, String> alarmMessages) {
        if (targetParameters != null) {
            Float motorSpeed = emaRecord.getMotorSpeed();
            Float motorCurrent = emaRecord.getMotorCurrent();
            Float temperature = emaRecord.getTemperature();
            Float supplyVoltage = emaRecord.getSupplyVoltage();
            Float targetRpm = targetParameters.getTargetRpm();

            Float targetCurrent = targetParameters.getTargetCurrent();
            Float minTempThresh = targetParameters.getMinTempThresh();
            Float maxTempThresh = targetParameters.getMaxTempThresh();
            Float minVoltThresh = targetParameters.getMinVoltThresh();
            Float maxVoltThresh = targetParameters.getMaxVoltThresh();

            Float rpmDiff = targetRpm - motorSpeed;
            Float currentDiff = targetCurrent - motorCurrent;

            Float temMindiff = temperature - minTempThresh;
            Float temMaxdiff = maxTempThresh - temperature;
            Float volMindiff = supplyVoltage - minVoltThresh;
            Float volMaxdiff = maxVoltThresh - supplyVoltage;

            if (currentDiff < 0) {
                alarmMessages.put("电流", "电流超过阈值" + Math.abs(temMaxdiff) + "A。");
            }
            if (rpmDiff < 0) {
                alarmMessages.put("转速", "转速超过阈值" + Math.abs(temMaxdiff) + "RPM。");
            }
            if (temMindiff < 0) {
                alarmMessages.put("温度", "温度低于阈值" + Math.abs(temMaxdiff) + "度。");
            }
            if (temMaxdiff < 0) {
                alarmMessages.put("温度", "温度高于阈值" + Math.abs(temMaxdiff) + "度。");
            }
            if (volMindiff < 0) {
                alarmMessages.put("电压", "电压低于阈值" + Math.abs(supplyVoltage) + "V。");
            }
            if (volMaxdiff < 0) {
                alarmMessages.put("电压", "电压高于阈值" + Math.abs(volMaxdiff) + "V。");
            }

        }
    }

    @Override
    public Result monitorWave(String name) {
        MonitorWaveVo monitorWaveVo = new MonitorWaveVo();
        LambdaQueryWrapper<Dict> targetParametersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        targetParametersLambdaQueryWrapper.gt(Dict::getId, 40000);
        targetParametersLambdaQueryWrapper.lt(Dict::getId, 50000);
        targetParametersLambdaQueryWrapper.eq(Dict::getDictCode, name);
        List<Dict> list = dictService.list(targetParametersLambdaQueryWrapper);
        if (list.size() == 1) {
            Dict dict = list.get(0);
            String name1 = dict.getName();
            Float upper = targetParametersMapper.getTargetParameters(name1);
            monitorWaveVo.setUpperValue(upper);
        }
        if (list.size() == 2) {
            Dict dict1 = list.get(0);
            String name1 = dict1.getName();
            Float down = targetParametersMapper.getTargetParameters(name1);
            monitorWaveVo.setDownValue(down);
            Dict dict2 = list.get(1);
            String name2 = dict2.getName();
            Float upper = targetParametersMapper.getTargetParameters(name2);
            monitorWaveVo.setUpperValue(upper);
        }

        LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(Dict::getId, 10000);
        queryWrapper.lt(Dict::getId, 20000);

        queryWrapper.eq(Dict::getName, name);
        queryWrapper.last("limit 1");
        Dict dict = dictService.getOne(queryWrapper);
        if (dict == null) throw new ImotExciption(500, "您输入参数有错，请检查后重新填入");

        String waveName = dict.getName();
        String convertName = convertName(waveName);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dateTime = now.minusMonths(30);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String date = dateTime.format(formatter);

        List<Map<Object, Object>> emaDataList = recordMapper.monitorWave(convertName, date);


        List<Float> numbers = new ArrayList<>();
        log.info("~~~~~~~~~~~~~~~{}", emaDataList);
        log.info("~~~~~~~~~~~~~~~{}", numbers);
// 遍历list，提取每个映射中的值
        for (Map<Object, Object> map : emaDataList) {
            Float value = (Float) map.get("value");
            numbers.add(value);
        }

        float calculateMean = calculateMean(numbers);   //均值
        float calculateRMS = calculateRMS(numbers);     //有效值
        float calculateKurtosis = calculateKurtosis(numbers);//峭度
        float findMax = findMax(numbers);               //最小值
        float findMin = findMin(numbers);               //最大值

        monitorWaveVo.setCalculateMean(calculateMean);
        monitorWaveVo.setCalculateRMS(calculateRMS);
        monitorWaveVo.setCalculateKurtosis(calculateKurtosis);
        monitorWaveVo.setFindMax(findMax);
        monitorWaveVo.setFindMin(findMin);
        monitorWaveVo.setEmaDataMap(emaDataList);
        return Result.success(monitorWaveVo);
    }

    public static String convertToSnakeCase(String input) {
        if (input == null) {
            return null;
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(input.charAt(0)));

        for (int i = 1; i < input.length(); i++) {
            char ch = input.charAt(i);
            if (Character.isUpperCase(ch)) {
                result.append('_');
                result.append(Character.toLowerCase(ch));
            } else {
                result.append(ch);
            }
        }

        return result.toString();
    }

    public static float calculateMean(List<Float> values) {
        float sum = 0;
        for (Float value : values) {
            sum += value;
        }
        return sum / values.size();
    }

    public static float calculateRMS(List<Float> values) {
        float squareSum = 0;
        for (Float value : values) {
            squareSum += value * value;
        }
        return (float) Math.sqrt(squareSum / values.size());
    }

    public static float calculateKurtosis(List<Float> values) {
        float mean = calculateMean(values);
        float standardDeviation = calculateStandardDeviation(values, mean);

        float sum = 0;
        for (Float value : values) {
            float diff = value - mean;
            sum += Math.pow(diff / standardDeviation, 4);
        }
        return sum / values.size();
    }

    public static float calculateStandardDeviation(List<Float> values, float mean) {
        float sum = 0;
        for (Float value : values) {
            sum += Math.pow(value - mean, 2);
        }
        return (float) Math.sqrt(sum / values.size());
    }

    public static float findMax(List<Float> values) {
        return Collections.max(values);
    }

    public static float findMin(List<Float> values) {
        return Collections.min(values);
    }

    @Override
    public Result getFaultTest(FaultTestDto faultTestDto) {
        String faultLevel = faultTestDto.getFaultLevel();
        String deviceName = faultTestDto.getDeviceName();
        LocalDateTime startDate = faultTestDto.getStartDate();
        LocalDateTime endDate = faultTestDto.getEndDate();
        PageHelper.startPage(faultTestDto.getPage(), faultTestDto.getLimit());
        LambdaQueryWrapper<EmaExceptionRecord> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(EmaExceptionRecord::getExceptionHandledFlag, 0);
        if (faultLevel != null) {
            queryWrapper.eq(EmaExceptionRecord::getExceptionLevel, faultLevel);
        }
        if (deviceName != null) {
            queryWrapper.eq(EmaExceptionRecord::getDeviceName, deviceName);
        }
        if (startDate != null) {
            queryWrapper.ge(EmaExceptionRecord::getDate, startDate);
        }
        if (endDate != null) {
            queryWrapper.le(EmaExceptionRecord::getDate, endDate);
        }

        List<EmaExceptionRecord> list = exceptionRecordService.list(queryWrapper);

        PageInfo<EmaExceptionRecord> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        List<EmaExceptionRecord> faultTests = pageInfo.getList();
        EmaExceptionRecordVo emaExceptionRecordVo = new EmaExceptionRecordVo();
        List<ExceptionRecordVo> exceptionRecordVos = new ArrayList<>();

        for (EmaExceptionRecord faultTest : faultTests) {
            ExceptionRecordVo exceptionRecordVo = new ExceptionRecordVo();
            BeanUtils.copyProperties(faultTest, exceptionRecordVo);
            exceptionRecordVos.add(exceptionRecordVo);
        }
        emaExceptionRecordVo.setTotal(total);
        emaExceptionRecordVo.setExceptionRecordVos(exceptionRecordVos);
        return Result.success(emaExceptionRecordVo);
    }

    @Override
    public Result deleteFaultTest(Integer id) {
        exceptionRecordService.removeById(id);
        return Result.success();
    }

    @Override
    public Result updateFaultTest(Integer id, String faultRight) {
        LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ge(Dict::getId, 20000);
        queryWrapper.lt(Dict::getId, 30000);
        queryWrapper.eq(Dict::getName, faultRight);
        Dict dict = dictService.getOne(queryWrapper);
        if (dict == null) throw new ImotExciption(500, "faultRight参数填写错误");
        Integer value = dict.getValue();

        EmaExceptionRecord faultTest = new EmaExceptionRecord();
        faultTest.setExceptionHandledFlag(value + "");
        exceptionRecordService.updateById(faultTest);
        return Result.success();
    }

    @Override
    public Result getHistoryData(FaultTestDto faultTestDto) {
        PageHelper.startPage(faultTestDto.getPage(), faultTestDto.getLimit());
        String faultLevel = faultTestDto.getFaultLevel();
        String deviceName = faultTestDto.getDeviceName();
        LocalDateTime startDate = faultTestDto.getStartDate();
        LocalDateTime endDate = faultTestDto.getEndDate();
        PageHelper.startPage(faultTestDto.getPage(), faultTestDto.getLimit());
        LambdaQueryWrapper<EmaExceptionRecord> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.in(EmaExceptionRecord::getExceptionHandledFlag, 1, 2);
        if (faultLevel != null) {
            queryWrapper.eq(EmaExceptionRecord::getExceptionLevel, faultLevel);
        }
        if (deviceName != null) {
            queryWrapper.eq(EmaExceptionRecord::getDeviceName, deviceName);
        }
        if (startDate != null) {
            queryWrapper.ge(EmaExceptionRecord::getDate, startDate);
        }
        if (endDate != null) {
            queryWrapper.le(EmaExceptionRecord::getDate, endDate);
        }

        List<EmaExceptionRecord> list = exceptionRecordService.list(queryWrapper);
        log.info("~~~~~~~~~~~list:{}", list);

        PageInfo<EmaExceptionRecord> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        List<EmaExceptionRecord> faultTests = pageInfo.getList();
        Map<Object, Object> hashMap = new HashMap<>();
        hashMap.put("total", total);
        hashMap.put("faultTests", faultTests);
        return Result.success(hashMap);
    }

    @Override
    public Result getFaultHistoryStatus() {
        DeviceStatusVo deviceStatusVo = new DeviceStatusVo();

        return Result.success(deviceStatusVo);
    }

    @Override
    public Result getHistoryExceptionConfirmation(Integer emaExceptionId) {
        EmaExceptionRecord exceptionRecord = exceptionRecordService.getById(emaExceptionId);
        if (exceptionRecord == null) throw new ImotExciption(500, "您查询的异常记录不存在");
        Integer emaRecordId = exceptionRecord.getEmaRecordId();
        Integer targetParametersId = exceptionRecord.getTargetParametersId();
        EmaRecord emaRecord = recordService.getById(emaRecordId);
        if (emaRecord == null) throw new ImotExciption(500, "您的数据记录异常，请联系管理员");
        TargetParameters targetParameters = targetService.getById(targetParametersId);
        if (targetParameters == null) throw new ImotExciption(500, "您的参数阈值记录异常，请联系管理员");

        String exceptionParameters = exceptionRecord.getExceptionParameters();
        Map<String, String> extractedData = extractData(exceptionParameters);
        Set<String> keySet = extractedData.keySet();
        ArrayList<String> list = new ArrayList<>(keySet);

        HistoryExceptionConfirmationVo historyExceptionConfirmationVo = new HistoryExceptionConfirmationVo();
        ArrayList<String> strings = new ArrayList<>();

        List<String> exceptions = new ArrayList<>();
        List<ExceptionDataVo> exceptionDataVos = new ArrayList<>();

        for (String s : list) {
            String s1 = extractedData.get(s);
            String exceptionData = s + "：" + s1;
            strings.add(exceptionData);

            ExceptionDataVo exceptionDataVo = new ExceptionDataVo();
            LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(Dict::getId, 10001);
            queryWrapper.lt(Dict::getId, 20000);
            queryWrapper.eq(Dict::getDictCode, s);
            Dict dict = dictService.getOne(queryWrapper);
            String name = dict.getName();
            String name1 = convertName(name);
            List<Map<Object, Object>> valueList = recordMapper.getRecordsAroundId(emaRecordId, name1);

            exceptionDataVo.setExceptionName(s + dict.getUnit());
            HashMap<LocalDateTime, Float> hashMap = new HashMap<>();
//            for (Map<Object, Object> map : valueList) {
//
//                LocalDateTime time = (LocalDateTime) map.get("time");
//                Float value = (Float) map.get("value");
//                hashMap.put(time, value);
//            }
            exceptionDataVo.setExceptionData(valueList);
            exceptions.add(exceptionData);
            exceptionDataVos.add(exceptionDataVo);
        }

        String deviceName = exceptionRecord.getDeviceName();
        String exceptionLocation = exceptionRecord.getExceptionLocation();
        Integer exceptionTime = exceptionRecord.getExceptionTime();
        LocalDateTime date = exceptionRecord.getDate();
        String exceptionLevel = exceptionRecord.getExceptionLevel();
        String exceptionHandledFlag = exceptionRecord.getExceptionHandledFlag();
        LocalDateTime confirmationTime = exceptionRecord.getConfirmationTime();
        Integer actuationCount = exceptionRecord.getActuationCount();

        historyExceptionConfirmationVo.setDeviceName(deviceName);
        historyExceptionConfirmationVo.setExceptionLocation(exceptionLocation);
        historyExceptionConfirmationVo.setExceptionTime(exceptionTime);
        historyExceptionConfirmationVo.setDate(date);
        historyExceptionConfirmationVo.setExceptionLevel(exceptionLevel);
        historyExceptionConfirmationVo.setExceptionHandledFlag(exceptionHandledFlag);
        historyExceptionConfirmationVo.setConfirmationTime(confirmationTime);
        historyExceptionConfirmationVo.setDeviceName("佳佳妞");
        historyExceptionConfirmationVo.setActuationCount(actuationCount);

        Integer userId = exceptionRecord.getUserId();


        historyExceptionConfirmationVo.setExceptionDataVos(exceptionDataVos);
        historyExceptionConfirmationVo.setExceptionParameters(exceptions);


        return Result.success(historyExceptionConfirmationVo);

    }

    @Override
    public Result getExceptionDetail(Integer id) {
        ExceptionDetailVo exceptionDetailVo = new ExceptionDetailVo();
        EmaExceptionRecord emaExceptionRecord = exceptionRecordService.getById(id);
        if (emaExceptionRecord == null) throw new ImotExciption(500, "入参id错误，找不到该id");

        Integer emaRecordId = emaExceptionRecord.getEmaRecordId();
        Integer targetParametersId = emaExceptionRecord.getTargetParametersId();

        String exceptionParameters = emaExceptionRecord.getExceptionParameters();
        String[] pairs = exceptionParameters.split("。\\s*");

        List<String> parameters = new ArrayList<>();
        List<String> values = new ArrayList<>();
        ArrayList<String> exceptionParameterList = new ArrayList<>();
        HashMap<String, String> exceptionParameterHashMap = new HashMap<>();

        for (String pair : pairs) {
            if (!pair.isEmpty()) {
                // 使用“：”分割每对参数和值
                String[] parts = pair.split("：");
                parameters.add(parts[0]); // 添加参数名称
                values.add(parts[1]); // 添加值
            }
        }
        for (int i = 0; i < parameters.size(); i++) {
            exceptionParameterHashMap.put(parameters.get(i), values.get(i));
        }

        log.info("------------------{}", parameters);
        ArrayList<DetailVo> detailVos = new ArrayList<>();
        for (String parameter : parameters) {
            LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Dict::getDictCode, parameter);
            queryWrapper.ge(Dict::getId, 10000);
            queryWrapper.lt(Dict::getId, 20000);
            Dict dict = dictService.getOne(queryWrapper);

            String unit = dict.getUnit();
            String value = exceptionParameterHashMap.get(parameter);
            String exceptionParameter = parameter + ":" + value + unit;
            exceptionParameterList.add(exceptionParameter);

            String name = dict.getName();
            String name1 = convertName(name);
            log.info("~~~~~~~~~~~~~~~{}", name1);
            List<Map<Object, Object>> valueList = recordMapper.getRecordsAroundId(emaRecordId, name1);
            Map<LocalDateTime, Float> hashMap = new HashMap<>();
            for (Map<Object, Object> map : valueList) {
                LocalDateTime time = (LocalDateTime) map.get("time");
                Float theValue = (Float) map.get("value");
                hashMap.put(time, theValue);
            }
            DetailVo detailVo = new DetailVo();
            detailVo.setWaveValues(valueList);
            LambdaQueryWrapper<ExceptionThresholds> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ExceptionThresholds::getExceptionParameter, parameter);
            wrapper.eq(ExceptionThresholds::getEmaExceptionRecordId, id);
            ExceptionThresholds exceptionThresholds = exceptionThresholdsService.getOne(wrapper);
            if (exceptionThresholds == null) throw new ImotExciption(500, "上下阈值出现错误，请联系管理员");
            Float upperThreshold = exceptionThresholds.getUpperThreshold();
            Float lowerThreshold = exceptionThresholds.getLowerThreshold();
            detailVo.setLowerThreshold(lowerThreshold);
            detailVo.setUpperThreshold(upperThreshold);
            detailVo.setParameter(parameter + unit);
            detailVos.add(detailVo);

            exceptionDetailVo.setWaveExceptionValueList(detailVos);
        }

        exceptionDetailVo.setExceptionTime(emaExceptionRecord.getDate());
        exceptionDetailVo.setExcepTionParatemers(exceptionParameterList);
        return Result.success(exceptionDetailVo);
    }

    @Override
    public Result getDescribeFault() {
        LambdaQueryWrapper<EmaExceptionRecord> emaExceptionRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        emaExceptionRecordLambdaQueryWrapper.orderByDesc(EmaExceptionRecord::getId);
        emaExceptionRecordLambdaQueryWrapper.eq(EmaExceptionRecord::getExceptionHandledFlag, 0);
        emaExceptionRecordLambdaQueryWrapper.last("limit 5");

        List<EmaExceptionRecord> list = exceptionRecordService.list(emaExceptionRecordLambdaQueryWrapper);
        List<Integer> ids = list.stream().map(EmaExceptionRecord::getEmaRecordId).collect(Collectors.toList());
        List<EmaRecord> emaRecords = recordService.listByIds(ids);
        List<String> deviceStatusList = emaRecords.stream().map(EmaRecord::getDeviceStatus).collect(Collectors.toList());
        List<String> specificPartList = emaRecords.stream().map(EmaRecord::getSpecificPart).collect(Collectors.toList());
        HashMap<String, List> hashMap = new HashMap<>();
        hashMap.put("deviceStatusList", deviceStatusList);
        hashMap.put("specificPartList", specificPartList);

        return Result.success(hashMap);
    }

    @Override
    public Result updateExceptionHistoryData(EmaExceptionRecord emaExceptionRecord) {
        exceptionRecordService.updateById(emaExceptionRecord);
        return Result.success();
    }

    @Override
    public Result getIp() {
        try {
            String localIP = null;
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface iface = interfaces.nextElement();
                // 过滤掉 loopback 接口、禁用的接口和虚拟接口
                if (iface.isLoopback() || !iface.isUp() || iface.isVirtual()) continue;

                Enumeration<InetAddress> addresses = iface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();

                    // 确保是IPv4地址且非本地回环地址
                    if (addr.getHostAddress().contains(".") && !addr.isLoopbackAddress()) {
                        localIP = addr.getHostAddress();
                        break;
                    }
                }
                if (localIP != null) {
                    break;
                }
            }
            if (localIP != null) {
                System.out.println("Local IP Address: " + localIP);
                return Result.success(localIP);
            } else {
                System.out.println("No local IP address found.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.success();
    }

    public String convertName(String name) {
        StringBuilder convertedName = new StringBuilder();

        for (char ch : name.toCharArray()) {
            if (Character.isUpperCase(ch)) {
                // 如果字符是大写字母，在前面添加横杠并转换为小写
                convertedName.append('_').append(Character.toLowerCase(ch));
            } else {
                // 如果不是大写字母，直接添加字符
                convertedName.append(ch);
            }
        }

        return convertedName.toString();
    }

    public static Map<String, String> extractData(String input) {
        Map<String, String> data = new LinkedHashMap<>();
        Pattern pattern = Pattern.compile("(\\p{IsHan}+)：([^。]+)。");
        Matcher matcher = pattern.matcher(input);

        while (matcher.find()) {
            String key = matcher.group(1); // 中文名称，如“温度”
            String value = matcher.group(2); // 对应的值，如“36.3℃”
            data.put(key, value);
        }

        return data;
    }

}

